package com.sl.utils.json;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Jackson 工具类
 *  @author zhangchao
 *  @version 1.0
 *  @date 2020-01-02 11:04:20
 */
public class MapperUtils {
    private final static ObjectMapper objectMapper = JacksonUtils.getCustomObjectMapperAddDeserializer();

    public static ObjectMapper getInstance() {
        return objectMapper;
    }

    /**
     * 将 JSON 数组转换为集合
     *
     * @param jsonArrayStr
     * @param clazz
     * @return
     * @throws Exception
     */
    public static <T> List<T> json2list(String jsonArrayStr, Class<T> clazz) throws Exception {
        JavaType javaType = getCollectionType(ArrayList.class, clazz);
        List<T> list = (List<T>) objectMapper.readValue(jsonArrayStr, javaType);
        return list;
    }

    /**
     * 将指定节点的 JSON 数组转换为集合
     * @param jsonStr JSON 字符串
     * @return
     * @throws Exception
     */
    public static <T> List<T> json2listByTree(String jsonStr, Class<T> clazz) throws  Exception {
        JsonNode jsonNode = objectMapper.readTree(jsonStr);
        return json2list(jsonNode.toString(), clazz);
    }

    /**
     * 获取泛型的 Collection Type
     *
     * @param collectionClass 泛型的Collection
     * @param elementClasses  元素类
     * @return JavaType Java类型
     * @since 1.0
     */
    public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }

    /**
     * 转换为 JSON 字符串
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static String obj2json(Object obj) throws Exception {
        return objectMapper.writeValueAsString(obj);
    }

    /**
     * 字符串转换为 Map<String, Object>
     *
     * @param jsonString
     * @return
     * @throws Exception
     */
    public static <T> Map<String, Object> json2map(String jsonString) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return mapper.readValue(jsonString, Map.class);
    }
    /**
     * JavaBean 转换为 Map
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static <T> Map<String, Object> obj2map(Object obj) throws Exception {
        String jsonString = obj2json(obj);
        return json2map(jsonString);
    }
}
